using System;
using System.Collections.Generic;
using System.Text;

using DslModeling = global::Microsoft.VisualStudio.Modeling;
using DslDiagrams = global::Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;

namespace Evaluant.EussDSL
{
    public abstract partial class EussDSLSerializationHelperBase
    {
        /// <summary>
        /// Customize Model Loading to add calculated elements.
        /// </summary>
        /// <param name="serializationResult">Stores serialization result from the load operation.</param>
        /// <param name="partition">Partition in which the new EussMapping instance will be created.</param>
        /// <param name="fileName">Name of the file from which the EussMapping instance will be deserialized.</param>
        /// <param name="modelRoot">The root of the file that was loaded.</param>
        private void OnPostLoadModel(DslModeling::SerializationResult serializationResult, DslModeling::Partition partition, string fileName, EussMapping modelRoot)
        {
            List<Entity> les = new List<Entity>();

            foreach (ModelElement me in partition.ElementDirectory.AllElements)
            {
                if (me is Entity)
                {
                    les.Add((Entity)me);
                }
            }

            Transaction tInheritance = partition.Store.TransactionManager.BeginTransaction();
            foreach (Entity element in les)
            {
                InheritanceDetector.DetectAndShow(element);
            }
            tInheritance.Commit();

            // OnPostLoadModel is ALWAYS fired, but OnPostLoadModelAndDiagram is not when the diagram
            // file doesn't exist
            GlobalData.isDiagramFilePresent = System.IO.File.Exists(fileName + ".diagram");
            GlobalData.numberOfEntities = les.Count;
        }

        /// <summary>
        /// Customize Model and Diagram Loading.
        /// </summary>
        /// <param name="serializationResult">Stores serialization result from the load operation.</param>
        /// <param name="modelPartition">Partition in which the new DslLibrary instance will be created.</param>
        /// <param name="modelFileName">Name of the file from which the DslLibrary instance will be deserialized.</param>
        /// <param name="diagramPartition">Partition in which the new DslDesignerDiagram instance will be created.</param>
        /// <param name="diagramFileName">Name of the file from which the DslDesignerDiagram instance will be deserialized.</param>
        /// <param name="modelRoot">The root of the file that was loaded.</param>
        /// <param name="diagram">The diagram matching the modelRoot.</param>
        private void OnPostLoadModelAndDiagram(DslModeling::SerializationResult serializationResult,
            DslModeling::Partition modelPartition,
            string modelFileName,
            DslModeling::Partition diagramPartition,
            string diagramFileName, EussMapping modelRoot, EussDSLDiagram diagram)
        {
            //List<Entity> les = new List<Entity>();

            foreach (ModelElement me in diagramPartition.ElementDirectory.AllElements)
            {
                if (me is ReferenceConnector)
                {
                    ReferenceConnector rc = (ReferenceConnector)me;
                    bool is11 = true;

                    //ce qu'il faut faire (en testant, etc):
                    if (rc.FromShape != null && rc.FromShape.ModelElement != null && rc.FromShape.ModelElement is Entity && rc.ToShape.ModelElement is Entity)
                    {
                        Entity source = ((Entity)(rc.FromShape.ModelElement));
                        Entity target = ((Entity)(rc.ToShape.ModelElement));

                        foreach (ModelElement me2 in diagramPartition.ElementDirectory.AllElements)
                        {
                            if (me2 is EntityReferencesTargets)
                            {
                                EntityReferencesTargets ert = (EntityReferencesTargets)me2;
                                if (ert.Source.type == source.type && ert.Target.type == target.type)
                                {
                                    // c'est une relation 1-* ou *-* si un des Identifiers de l'entite source est le parentField de la relation courante
                                    foreach (Identifier identifier in source.Identifiers)
                                    {
                                        if (identifier.field == ert.parentField)
                                        {
                                            is11 = false;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    if (is11)
                    {
                        rc.DecoratorTo = LinkDecorator.DecoratorEmptyArrow;
                        rc.DecoratorFrom = LinkDecorator.DecoratorEmptyArrow;

                        Transaction t = diagramPartition.Store.TransactionManager.BeginTransaction();
                        rc.SourceMultiplicity = "1";
                        rc.TargetMultiplicity = "1";
                        t.Commit();
                    }
                    else
                    {
                        rc.DecoratorTo = LinkDecorator.DecoratorEmptyArrow;
                        rc.DecoratorFrom = null;

                        Transaction t = diagramPartition.Store.TransactionManager.BeginTransaction();
                        rc.SourceMultiplicity = "1";
                        rc.TargetMultiplicity = "*";
                        t.Commit();
                    }
                }
                //else if (me is Entity)
                //{
                //    les.Add((Entity)me);
                //}
            }

            //Transaction tInheritance = diagramPartition.Store.TransactionManager.BeginTransaction();
            //foreach (Entity element in les)
            //{
            //    InheritanceDetector.DetectAndShow(element);
            //}
            //tInheritance.Commit();
        }
    }
}
